/**
 * @author: Miss.杨
 * @date: 2024年12月29日 21:30:27
 * @description: 
 */
package com.sheepone.monitor.server;

import com.sheepone.monitor.runner.AbstractMonitorRunner;
import com.sheepone.monitor.runner.listener.MonitorRunnerListenerAdapter;
import com.sheepone.monitor.server.config.MonitorServerConfig;
import com.sheepone.webdev.log.WebDevLogger;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author: Miss.杨
 * @date: 2024年12月29日 21:30:27
 * @description:
 */
public class MonitorServerRunner<C extends MonitorServerConfig, I extends BaseMonitorSeverChannelInitializer>
        extends AbstractMonitorRunner<C, I> {
    private static WebDevLogger logger = WebDevLogger.getLogger(MonitorServerRunner.class);

    public MonitorServerRunner(C config) {
        super(config);
    }

    private NioEventLoopGroup bossGroup;
    private NioEventLoopGroup workerGroup;

    @Override
    protected void shutdown() {
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }

    @Override
    public void beforeStart() {
        bossGroup = new NioEventLoopGroup(config.getBossThreads());
        workerGroup = new NioEventLoopGroup(config.getWorkerThreads());
        addListener(new MonitorRunnerListenerAdapter() {
            @Override
            public void startSuccessfully(Channel channel) {
                logger.info("MonitorServer[{}] run on port:{} successfully", config.getName(), config.getPort());
            }
        });
    }

    @Override
    protected ChannelFuture start(I channelInitializer) throws Exception {
        // ! 服务端入口 用于Accept事件的监听与处理
        ServerBootstrap serverBootstrap = new ServerBootstrap()
                // ! 设置TCP接收缓冲区大小
                // .option(ChannelOption.SO_RCVBUF, 1024)
                // ! 设置netty接收缓冲区大小
                // .childOption(ChannelOption.RCVBUF_ALLOCATOR, new
                // AdaptiveRecvByteBufAllocator(1024, 1024, 1024))
                // ! group可以传递一个参数也可以两个，两个的话可以让分工更细化
                // ! 前一个用于处理ServerSocketChannel的Accept事件
                // ! 后一个用于处理SocketChannel的Read/Write事件的线程组
                // ! EventLoopGroup 通过调用next()执行每一个客户端所分配到的EventLoop
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                // ! 这里添加的是EventLoop在每接受到一个SocketChannel的时候需要添加的ChannelHandler
                .childHandler(channelInitializer);
        // ! 同步绑定端口，确保拿到的ChannelFuture!=null
        return serverBootstrap.bind(config.getPort()).sync();
    }
}
